/*
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 *
 * Copyright @2008 the original author or authors.
 */
package com.bluestone.scripts;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

import bsh.Interpreter;

import com.bluestone.context.ProjectContext;
import com.bluestone.util.Util;

/**
 * A input is corresponse to a testSuite which containts testCases and functions
 * or corresponse to module which contains a set of the pages and the elements.
 * 
 * @author <a href="mailto:bluestone.daniel.q@gmail.com">daniel.q</a>
 */

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "input", propOrder = { "file", "type", "obj" })
public class Input {

	@XmlElement(name = "file")
	private String file;

	@XmlElement(name = "type")
	private String type;

	@XmlElement(name = "obj")
	private Object obj;

	public String getFile() {
		return file;
	}

	public void setFile(String file) {
		this.file = file;
	}

	public void loadObject(ProjectContext context) {
		if ("module".equalsIgnoreCase(type)) {
			obj = Util.loadObjectFromFile(getFile(), Module.class);
			context.addExecuteLog("load module file " + getFile());
		} else if ("library".equalsIgnoreCase(type)) {
			obj = Util.loadObjectFromFile(getFile(), Library.class);
			context.addExecuteLog("load library file " + getFile());
		} else {
			obj = Util.loadObjectFromFile(getFile(), TestSuite.class);
			context.addExecuteLog("load testsuite file " + getFile());
		}
	}

	public Object getObject() {
		return obj;

	}


	public String toString() {
		String str = "input:";
		if (file != null) {
			str = str + "file=" + file;
		}
		return (str);
	}

	/**
	 * According the path to find the page.
	 * 
	 * @param path
	 * @return
	 */
	public Page searchPage(String path) {
		Page page = null;
		if (obj != null && Module.class.isInstance(obj)) {
			Module module = (Module) obj;
			ArrayList pages = (ArrayList) module.getPages();

			for (int i = 0; i < pages.size(); i++) {
				Page temp = (Page) pages.get(i);
				if (path.equalsIgnoreCase(temp.getSearchPath())) {
					String owner = temp.getOwner();
					boolean isfind = false;
					if (owner == null) {
						page = temp;
					} else {
						try {
							List<Property> properties = ProjectContext.getInstance(null).getProject().getProperties();
							Interpreter interpreter = new Interpreter();
							for (Property property : properties) {
								if(ResourceBundle.class.isInstance(property.getObject())){
									ResourceBundle rb =(ResourceBundle)property.getObject();
									java.util.Enumeration en = rb.getKeys();
									while(en.hasMoreElements()){
										String key =(String)en.nextElement();
										String value = rb.getString(key);
										interpreter.set(key,value);
									}
									
								}								
							}
							if (((Boolean) interpreter.eval(owner))
									.booleanValue()) {
								return temp;
							}
						} catch (Exception me) {
							Util.getLogger().error("input searchpage " + me);
						}
					}
				}
			}
		}

		return page;
	}

	/**
	 * According the path to find the Function.
	 * 
	 * @param path
	 * @return
	 */
	public Function searchFunction(String path) {

		if (obj != null && Library.class.isInstance(obj)) {
			Library library = (Library) obj;

			ArrayList list = (ArrayList) library.getFunctions();
			for (int i = 0; i < list.size(); i++) {
				Function function = (Function) list.get(i);
				if (path.indexOf(".") >= 0) {
					if (path.equalsIgnoreCase(library.getName() + "."
							+ function.getName())) {
						return function;
					}
				} else {
					if (path.equalsIgnoreCase(function.getName())) {
						return function;
					}
				}
			}
		}
		return null;
	}

	/**
	 * According the path to find the Element.
	 * 
	 * @param path
	 * @return
	 */
	public Element searchElement(String path) {

		Element element = null;
		Page page = null;
		String pagePath = null;
		String elementPath = null;
		if (path.indexOf("|") > 0) {
			pagePath = path.substring(0, path.lastIndexOf("|"));
			elementPath = path;
		}

		if (pagePath != null) {
			page = searchPage(pagePath);
		} else {
			page = Util.getCurrentPage();
			elementPath = page.getSearchPath() + "|" + path;
		}
		if (page != null) {
			ArrayList elements = (ArrayList) page.getElements();
			for (int j = 0; j < elements.size(); j++) {
				Element temp = (Element) elements.get(j);
				if (elementPath.equalsIgnoreCase(temp.getSearchPath())) {
					return temp;
				}
			}
		}
		return element;
	}

	/**
	 * According the path to find the TestCase.
	 * 
	 * @param path
	 * @return
	 */
	public TestCase searchTestCase(String path) {

		if (obj != null && TestSuite.class.isInstance(obj)) {
			TestSuite testsuite = (TestSuite) obj;

			ArrayList list = (ArrayList) testsuite.getTestcases();
			for (int i = 0; i < list.size(); i++) {
				TestCase testcase = (TestCase) list.get(i);
				if (testcase.getSearchPath().equalsIgnoreCase(path)) {
					return testcase;
				}
			}
		}
		return null;
	}

	/**
	 * According the path to find the Command.
	 * 
	 * @param path
	 * @return
	 */
	public Command searchCommand(String path) {

		if (obj != null && TestSuite.class.isInstance(obj)) {
			TestSuite testsuite = (TestSuite) obj;
			ArrayList list = (ArrayList) testsuite.getTestcases();
			for (int i = 0; i < list.size(); i++) {
				TestCase testcase = (TestCase) list.get(i);
				Command command = testcase.searchCommand(path);
				if (command != null) {
					return command;
				}
			}
		}
		return null;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

}
